var fs = require('fs')
var readLine = require('readline')
const rows = 2000

const log2File = (file, data) => {
  if (!fs.existsSync(process.env.absolutePath + '/log/')) {
    fs.mkdir(process.env.absolutePath + '/log/')
  }
  fs.appendFile(
    process.env.absolutePath + '/log/' + file,
    data + '\n',
    'utf8',
    function(err) {
      if (err) {
        console.log(err)
      }
    }
  )
}

const trimFile = file => {
  if (!fs.existsSync(process.env.absolutePath + '/log/')) {
    fs.mkdir(process.env.absolutePath + '/log/')
  }
  if (fileWatchers[file]) {
    return
  }
  var readstream = fs.createReadStream(
    process.env.absolutePath + '/log/' + file
  )
  var lineRead = readLine.createInterface({
    input: readstream
  })
  let lines = []
  lineRead
    .on('line', data => {
      lines.push(data)
      if (lines.length > 2500) {
        lines = lines.slice(500)
      }
    })
    .on('close', () => {
      if (lines.length >= 2000) {
        let start = lines.length > rows ? lines.length - rows : 0
        fs.writeFile(
          process.env.absolutePath + '/log/' + file,
          lines.slice(start).join('\n')
        )
      }
    })
}

const watchFile = (fileName, cb) => {
  if (!fs.existsSync(process.env.absolutePath + '/log/')) {
    fs.mkdir(process.env.absolutePath + '/log/')
  }
  fs.watchFile(process.env.absolutePath + '/log/' + fileName, cb)
}

const unwatchFile = fileName => {
  if (!fs.existsSync(process.env.absolutePath + '/log/')) {
    fs.mkdir(process.env.absolutePath + '/log/')
  }
  fs.unwatchFile(process.env.absolutePath + '/log/' + fileName)
}

const readFileRange = (fileName, range, cb) => {
  let rl = readLine.createInterface({
    input: fs.createReadStream(process.env.absolutePath + '/log/' + fileName, {
      enconding: 'utf8',
      start: range.range
    })
  })
  rl.on('line', function(line) {
    cb && cb(line)
    range.range += line.length + 1
  })
  rl.on('end', () => {
    rl.close()
  })
}

const fileWatchers = {}

const registerFileWatch = (file, watcherCb) => {
  if (!fileWatchers[file]) {
    fileWatchers[file] = []
    watchFile(file, (curr, prev) => {
      if (curr.mtime > prev.mtime) {
        fileWatchers[file].forEach(w => {
          readFileRange(file, w, w.cb)
        })
      }
    })
  }
  let watcher = {
    cb: watcherCb,
    range: 0
  }
  fileWatchers[file].push(watcher)
  readFileRange(file, watcher, watcherCb)
}

const unregisterFileWatcher = (file, watcherCb) => {
  if (fileWatchers[file]) {
    fileWatchers[file] = fileWatchers[file].filter(w => {
      if (w.cb === watcherCb) {
        return false
      }
      return true
    })
    if (fileWatchers[file].length === 0) {
      unwatchFile(file)
      delete fileWatchers[file]
    }
  }
}

module.exports = {
  trimFile,
  log2File,
  registerFileWatch,
  unregisterFileWatcher
}
